﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Matrix.Common.Utility;
using Matrix.MaKaYunShang.Model;
using Matrix.MaKaYunShang.Model.Enum;

namespace Matrix.MaKaYunShang.BLL.CloudCard
{
    public class CloudCardBll
    {

        /// <summary>
        /// 抽奖品
        /// </summary>
        /// <param name="scanEvent">扫码记录</param>
        /// <returns></returns>
        public CloudCards GetAward(ScanEvent scanEvent)
        {
            CloudCards result = null;
            //余额警戒值（默认值20元）
            int awardLimitMinAmount;
            if (!int.TryParse(ConfigurationManager.AppSettings["AwardLimitMinAmount"], out awardLimitMinAmount))
            {
                awardLimitMinAmount = 20;
            }
            var cardRuleBase = CardRuleBaseBLL.Instance.GetModelByShopId(scanEvent.ShopId) ?? new CardRuleBase { WeightValue = 100 };//cardRuleBase如为null，则传入0，兼容处理店铺未配置卡券和规则的情况
            var timeSpanAwardList = CanCardFilter(cardRuleBase.Id, scanEvent.ShopId, awardLimitMinAmount);
            //当前可参与抽奖的奖品的设置总数
            if (timeSpanAwardList.Count > 0)
            {
                if (timeSpanAwardList.Count(l => l.IsHeadquarters) > 0 && timeSpanAwardList.Count(l => !l.IsHeadquarters) > 0)
                {
                    var headquartersPercent = 0;//总部券概率（0-100）%
                    var sysConfig = SysConfigBLL.Instance.GetModelList();
                    if (sysConfig.Count > 0)
                    {
                        headquartersPercent = sysConfig[0].HeadquartersCardsPercent;//0-100
                    }
                    var ranPercentNum = new Random().Next(1, 101);
                    //以1-100为基数进行总部或分店卡券筛选
                    if (ranPercentNum >= 1 && ranPercentNum <= headquartersPercent)
                    {
                        timeSpanAwardList = timeSpanAwardList.FindAll(l => l.IsHeadquarters);
                        cardRuleBase.WeightValue = 100;
                    }
                    else
                    {
                        timeSpanAwardList = timeSpanAwardList.FindAll(l => !l.IsHeadquarters);
                    }
                }
                #region 新抽奖逻辑（按奖品比例）
                //奖品范围基数值（1,100;101,300;301,900;......根据以下算法得出，临界不重复）
                var countRangeList = new List<List<int>>();
                //当前所有奖品总数累加和
                var currentAllTotalCount = 0;
                //计算奖品范围基数值
                foreach (var item in timeSpanAwardList)
                {
                    countRangeList.Add(new List<int> { currentAllTotalCount + 1, currentAllTotalCount + item.CardTotalQuantity });
                    currentAllTotalCount += item.CardTotalQuantity;
                }
                //根据百分比重新计算随机基数
                var baseCount = int.Parse(Math.Ceiling(currentAllTotalCount / (cardRuleBase.WeightValue / 100.0)).ToString());
                //以所有奖品总数累加和为上限，1为下限，随机出一位数
                var randomNum = new Random().Next(1, baseCount + 1);
                //奖品序号
                int? awardIndex = null;
                for (var i = 0; i < countRangeList.Count; i++)
                {
                    //判断随机数是否在某个范围基数内，奖品总数范围值越大，中奖几率越高
                    if (countRangeList[i][0] <= randomNum && countRangeList[i][1] >= randomNum)
                    {
                        //如果在范围内，则为奖品序号赋值
                        awardIndex = i;
                        break;
                    }
                }
                if (awardIndex.HasValue)
                {
                    //根据奖品序号取得奖品Id，并获取奖品信息返回
                    result = CloudCardsBLL.Instance.GetModelById(timeSpanAwardList[awardIndex.Value].CloudCardId);
                    if (result != null)
                    {
                        result.CategoryCode = timeSpanAwardList[awardIndex.Value].CategoryCode;
                        result.LoGo = timeSpanAwardList[awardIndex.Value].LoGo;
                        result.ScanId = scanEvent.Id;
                        result.Title = timeSpanAwardList[awardIndex.Value].Title;
                    }
                }
                #endregion
            }
            //返回null则未中奖
            return result;
        }

        /// <summary>
        /// 卡劵过滤
        /// </summary>
        /// <param name="cardRuleBaseId">卡券规则Id</param>
        /// <param name="shopId">店铺id</param>
        /// <param name="awardLimitMinAmount">余额警戒值</param>
        public List<CardRuleDetail> CanCardFilter(int cardRuleBaseId, int shopId, int awardLimitMinAmount)
        {
            var now = DateTime.Now;
            var shopSubsidiaryInfo = ShopSubsidiaryInfoBLL.Instance.GetModelList(string.Format("ShopId={0}", shopId)).FirstOrDefault();
            var timeSpanAwardList = cardRuleBaseId > 0 ? CardRuleDetailBLL.Instance.GetModelByRuleBaseId(cardRuleBaseId) : new List<CardRuleDetail>();//兼容处理店铺未配置卡券和规则的情况
            var shop = ShopsBLL.Instance.GetModel(shopId);
            if (shop != null && shop.ParentShopId > 0)
            {
                var parentCardRuleBase = CardRuleBaseBLL.Instance.GetModelByShopId(shop.ParentShopId);
                var parentTimeSpanAwardList = new List<CardRuleDetail>();
                if (parentCardRuleBase != null)
                {
                    parentTimeSpanAwardList = CardRuleDetailBLL.Instance.GetModelByRuleBaseId(parentCardRuleBase.Id);
                }
                var cloudCardsList = CloudCardsBLL.Instance.GetModelList("ShopId=" + shop.ParentShopId + " and PassStatus=" + (int)CloudCardEnum.CloudCardsPassStatus.审核通过);
                //剔除不可使用总部卡券的店铺
                cloudCardsList = cloudCardsList.Where(l => string.IsNullOrEmpty(l.UsableShopIds) || l.UsableShopIds.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries).Contains(shopId.ToString())).ToList();
                parentTimeSpanAwardList = parentTimeSpanAwardList.FindAll(l => cloudCardsList.Find(s => s.Id == l.CloudCardId) != null);
                var parentShopSubsidiaryInfo = ShopSubsidiaryInfoBLL.Instance.GetModelList(string.Format("ShopId={0}", shop.ParentShopId)).FirstOrDefault();
                //总部可发次数判断
                if (parentShopSubsidiaryInfo != null && parentShopSubsidiaryInfo.TotalCanSendCard > parentShopSubsidiaryInfo.AlreadySendCard && parentTimeSpanAwardList.Count > 0)
                {
                    timeSpanAwardList.AddRange(parentTimeSpanAwardList.Select(s => new CardRuleDetail
                   {
                       Title = s.Title,
                       LoGo = s.LoGo,
                       CategoryCode = s.CategoryCode,
                       CloudCardId = s.CloudCardId,
                       IsHeadquarters = true,
                       ShopId = s.ShopId,
                       StartTime = s.StartTime,
                       EndTime = s.EndTime,
                       CardTotalQuantity = s.CardTotalQuantity,
                       CardSendQuantity = s.CardSendQuantity,
                       CardName = s.CardName,
                       CardValue = s.CardValue,
                       ShowOnHomepage = s.ShowOnHomepage
                   }).ToList());
                }
            }
            //如果每日已发数量>=每日可发数量就排除抽奖列表||开始时间小于当前时间||当前时间大于结束时间
            timeSpanAwardList = timeSpanAwardList.Where(t => t.CardTotalQuantity > t.CardSendQuantity && t.EndTime >= now && now >= t.StartTime).ToList();
            if (shopSubsidiaryInfo == null || shopSubsidiaryInfo.AccountMoney < awardLimitMinAmount || shopSubsidiaryInfo.TotalCanSendCard <= shopSubsidiaryInfo.AlreadySendCard)//商家没有余额或者可用次数排除商家劵 
            {
                timeSpanAwardList.RemoveAll(r => r.IsHeadquarters == false);//移除非总部店铺卡劵
            }
            return timeSpanAwardList;
        }

        /// <summary>
        /// 抽别家劵 
        /// </summary>
        public CloudCards OtherCard(ScanEvent scan, int searchShopRadius)
        {
            var dtTime = DateTime.Now;
            int separatedIndustryId = 0;
            int parentShopId = 0;
            var shops = ShopsBLL.Instance.GetModel(scan.ShopId);
            if (shops != null && shops.Id > 0)
            {
                if (string.IsNullOrEmpty(scan.Longitude) && string.IsNullOrEmpty(scan.Latitude))
                {
                    scan.Longitude = shops.Longitude;
                    scan.Latitude = shops.Latitude;
                }
                parentShopId = shops.ParentShopId;
                separatedIndustryId = shops.SeparatedIndustryId;
            }
            //排除自己 搜寻该GPS位置附近的商户 查询有库存的卡劵
            var merchantList = CardRuleDetailBLL.Instance.GetModelListByWhere(scan.Longitude, scan.Latitude, searchShopRadius, string.Format(" cc.ShopId!={0} and s.SeparatedIndustryId!={1} and (ss.TotalCanSendCard-ss.AlreadySendCard)>0  and cc.ShopId!={2}", scan.ShopId, separatedIndustryId, parentShopId));
            //如果每日已发数量>=每日可发数量就排除抽奖列表||开始时间小于当前时间||当前时间大于结束时间
            merchantList = merchantList.Where(t => t.CardTotalQuantity > t.CardSendQuantity && t.EndTime >= dtTime && dtTime >= t.StartTime).ToList();
            Random rd = new Random();
            int m = -1;
            if (merchantList.Count > 0) //如果不等于空取出一个随机卡劵
            {
                m = rd.Next(0, merchantList.Count);
            }
            return m > -1 ? new CloudCards()
            {
                ShopId = merchantList[m].ShopId,
                Id = merchantList[m].CloudCardId,
                CategoryCode = merchantList[m].CategoryCode,
                ScanId = scan.Id,
                LoGo = merchantList[m].LoGo,
                Title = merchantList[m].Title,
                CardName = merchantList[m].CardName,
                CardValue = merchantList[m].CardValue,
                ShopName = merchantList[m].ShopName,
                StartTime = merchantList[m].StartTime,
                EndTime = merchantList[m].EndTime,
                Instruction = merchantList[m].Instruction
            } : null;
        }

        /// <summary>
        /// 外部接口方法
        /// </summary>
        /// <param name="scan"></param>
        /// <param name="searchShopRadius"></param>
        ///<remarks>默认不发送美食类卡劵 硬编码id!=1</remarks>
        public CloudCards ThirdOtherCard(ScanEvent scan, int searchShopRadius)
        {
            var dtTime = DateTime.Now;
            int separatedIndustryId = 0;
            int parentShopId = 0;
            var shops = ShopsBLL.Instance.GetModel(scan.ShopId);
            if (shops != null && shops.Id > 0)
            {
                if (string.IsNullOrEmpty(scan.Longitude) && string.IsNullOrEmpty(scan.Latitude))
                {
                    scan.Longitude = shops.Longitude;
                    scan.Latitude = shops.Latitude;
                }
                parentShopId = shops.ParentShopId;
                separatedIndustryId = shops.SeparatedIndustryId;
            }
            //排除自己 搜寻该GPS位置附近的商户 查询有库存的卡劵 todo暂时硬编码 searchShopRadius=20000000
            var merchantList = CardRuleDetailBLL.Instance.GetModelListByWhere(scan.Longitude, scan.Latitude, 20000000, string.Format(" cc.ShopId!={0} and s.SeparatedIndustryId!={1} and (ss.TotalCanSendCard-ss.AlreadySendCard)>0  and cc.ShopId!={2} and s.IndustryId!=1", scan.ShopId, separatedIndustryId, parentShopId));
            //如果每日已发数量>=每日可发数量就排除抽奖列表||开始时间小于当前时间||当前时间大于结束时间
            merchantList = merchantList.Where(t => t.CardTotalQuantity > t.CardSendQuantity && t.EndTime >= dtTime && dtTime >= t.StartTime).ToList();
            Random rd = new Random();
            int m = -1;
            if (merchantList.Count > 0) //如果不等于空取出一个随机卡劵
            {
                m = rd.Next(0, merchantList.Count);
            }
            return m > -1 ? new CloudCards()
            {
                ShopId = merchantList[m].ShopId,
                Id = merchantList[m].CloudCardId,
                CategoryCode = merchantList[m].CategoryCode,
                ScanId = scan.Id,
                LoGo = merchantList[m].LoGo,
                Title = merchantList[m].Title,
                CardName = merchantList[m].CardName,
                CardValue = merchantList[m].CardValue,
                ShopName = merchantList[m].ShopName,
                StartTime = merchantList[m].StartTime,
                EndTime = merchantList[m].EndTime,
                Instruction = merchantList[m].Instruction
            } : null;
        }

        /// <summary>
        /// 平台劵
        /// </summary>
        /// <param name="scan">ScanEvent</param>
        /// <returns></returns>
        public CloudCards PlatformCard(ScanEvent scan)
        {
            CloudCards result = null;
            var now = DateTime.Now;
            int separatedIndustryId = 0;
            var shops = ShopsBLL.Instance.GetModel(scan.ShopId);
            if (shops != null)
            {
                separatedIndustryId = shops.SeparatedIndustryId;
            }
            int platformShopIds = int.Parse(System.Configuration.ConfigurationManager.AppSettings["PlatformShopIds"]);
            if (platformShopIds < 1)
            {
                return null;
            }
            var cardRuleBase = CardRuleBaseBLL.Instance.GetModelByShopId(platformShopIds) ?? new CardRuleBase { WeightValue = 100 };//cardRuleBase如为null，则传入0，兼容处理店铺未配置卡券和规则的情况
            if (cardRuleBase.Id > 0)
            {
                var timeSpanAwardList = cardRuleBase.Id > 0 ? CardRuleDetailBLL.Instance.GetModelByRuleBaseId(cardRuleBase.Id) : new List<CardRuleDetail>();//兼容处理店铺未配置卡券和规则的情况
                timeSpanAwardList = timeSpanAwardList.Where(
               l => string.IsNullOrEmpty(l.DisabledSeparatedIndustryIds) || !l.DisabledSeparatedIndustryIds.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries).Contains(separatedIndustryId.ToString())).ToList();
                timeSpanAwardList = timeSpanAwardList.Where(t => t.CardTotalQuantity > t.CardSendQuantity && t.EndTime >= now && now >= t.StartTime).ToList();
                if (timeSpanAwardList.Count > 0)
                {
                    #region 新抽奖逻辑（按奖品比例）
                    var countRangeList = new List<List<int>>();
                    var currentAllTotalCount = 0;
                    foreach (var item in timeSpanAwardList)
                    {
                        countRangeList.Add(new List<int> { currentAllTotalCount + 1, currentAllTotalCount + item.CardTotalQuantity });
                        currentAllTotalCount += item.CardTotalQuantity;
                    }
                    var baseCount = int.Parse(Math.Ceiling(currentAllTotalCount / (cardRuleBase.WeightValue / 100.0)).ToString());
                    var randomNum = new Random().Next(1, baseCount + 1);
                    int? awardIndex = null;
                    for (var i = 0; i < countRangeList.Count; i++)
                    {
                        if (countRangeList[i][0] <= randomNum && countRangeList[i][1] >= randomNum)
                        {
                            awardIndex = i;
                            break;
                        }
                    }
                    if (awardIndex.HasValue)
                    {
                        //根据奖品序号取得奖品Id，并获取奖品信息返回
                        result = CloudCardsBLL.Instance.GetModelById(timeSpanAwardList[awardIndex.Value].CloudCardId);
                        if (result != null)
                        {
                            result.CategoryCode = timeSpanAwardList[awardIndex.Value].CategoryCode;
                            result.LoGo = timeSpanAwardList[awardIndex.Value].LoGo;
                            result.ScanId = scan.Id;
                            result.Title = timeSpanAwardList[awardIndex.Value].Title;
                        }
                    }
                    #endregion
                }
                return result;
            }
            return null;
        }

        /// <summary>
        /// 添加卡劵
        /// </summary>
        /// <param name="cardId">卡卷id</param>
        /// <param name="userId">用户id</param>
        /// <param name="latitude">latitude</param>
        /// <param name="longitude">longitude</param>
        /// <param name="shopId">店铺id</param>
        /// <param name="scanEventShopId">扫码店铺id</param>
        /// <returns></returns>
        public int AddUserCard(int cardId, int userId, string latitude, string longitude, int shopId, int scanEventShopId)
        {
            int sendCardShopId = 0;
            var shop = ShopsBLL.Instance.GetModel(shopId);
            if (shop == null)
            {
                return 0;
            }
            if (!shop.IsHeadquarters)
            {
                sendCardShopId = scanEventShopId == shopId ? 0 : scanEventShopId;
            }
            var cardRuleBase = CardRuleBaseBLL.Instance.GetModelByShopId(shopId);
            if (cardRuleBase != null)
            {
                //筛选出当前时间段的抽奖规则
                var cardRuleDetail = CardRuleDetailBLL.Instance.GetModelByRuleBaseId(cardRuleBase.Id, cardId);
                int cardNum = UserCardBLL.Instance.GetModelByCloudCardIdCount(cardId);
                if (cardRuleDetail != null && cardRuleDetail.CardTotalQuantity > cardNum)
                {
                    cardRuleDetail.CardSendQuantity = cardRuleDetail.CardSendQuantity + 1;
                    CardRuleDetailBLL.Instance.Update(cardRuleDetail);
                }
            }
            var cloudCard = CloudCardsBLL.Instance.GetModel(cardId);
            return cloudCard == null ? 0 : AddUserCard(cloudCard, latitude, longitude, sendCardShopId, userId);
        }
        //添加用户卡劵
        public int AddUserCard(CloudCards cloudCard, string latitude, string longitude, int sendCardShopId, int userId)
        {
            UserCard model = new UserCard()
            {
                AddTime = DateTime.Now,
                CardCode = GetCode(cloudCard.CategoryCode),
                CardStatus = (int)CloudCardEnum.UserCardStatus.未使用,
                CloudCardId = cloudCard.Id,
                Latitude = latitude,
                Longitude = longitude,
                ShopId = cloudCard.ShopId,
                ReceiveIp = IpHelper.IPAddress,
                ReceiveSource = (int)cloudCard.ReceiveSource,
                ReceiveUserId = userId,
                SendCardShopId = sendCardShopId
            };
            return UserCardBLL.Instance.Add(model);
        }
        //修改店铺账号信息
        public bool AddShopSubsidiaryInfo(ShopSubsidiaryInfo shopSubsidiaryInfo)
        {
            shopSubsidiaryInfo.AlreadySendCard = shopSubsidiaryInfo.AlreadySendCard + 1;
            shopSubsidiaryInfo.UpdateTime = DateTime.Now;
            return ShopSubsidiaryInfoBLL.Instance.Update(shopSubsidiaryInfo);
        }

        /// <summary>
        /// 生成code码
        /// </summary>
        /// <param name="categoryCode">类别code</param>
        /// <returns></returns>
        public string GetCode(string categoryCode)
        {
            var code = categoryCode + StringExtension.GenerateCheckCodeNum(8);
            var model = UserCardBLL.Instance.GetModelByCardCode(code);
            if (model != null)
            {
                GetCode(categoryCode);
            }
            return code;
        }
    }
}
